package com.example.skillcinema.ui.screens.main.viewmodels

import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.example.skillcinema.db.displaymodels.FilmDisplayModel
import com.example.skillcinema.db.localdb.tables.CollectionEntity
import com.example.skillcinema.db.localdb.tables.FilmCollectionCrossRef
import com.example.skillcinema.db.localdb.tables.FilmEntity
import com.example.skillcinema.db.models.Film
import com.example.skillcinema.db.models.Season
import com.example.skillcinema.db.models.Staff
import com.example.skillcinema.db.repositories.FilmForPreviewRepository
import com.example.skillcinema.db.responses.ImageItemResponse
import com.example.skillcinema.db.responses.RelatedFilmItemResponse
import dagger.hilt.android.lifecycle.HiltViewModel
import jakarta.inject.Inject
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.launch

@HiltViewModel
class FilmDetailViewModel @Inject constructor(val repository: FilmForPreviewRepository) :
    ViewModel() {
    private val _filmDataStateFlow: MutableStateFlow<Film?> = MutableStateFlow(null)
    val filmDataFlow = _filmDataStateFlow.asStateFlow()

    private val _seasonAndSeriesStateFlow: MutableStateFlow<List<Season>> =
        MutableStateFlow(listOf())
    val seasonAndSeriesFlow = _seasonAndSeriesStateFlow.asStateFlow()

    private val _actorsStateFlow: MutableStateFlow<List<Staff>> = MutableStateFlow(listOf())
    val actorsFlow = _actorsStateFlow.asStateFlow()

    private val _staffStateFlow: MutableStateFlow<List<Staff>> = MutableStateFlow(listOf())
    val staffFlow = _staffStateFlow.asStateFlow()

    private val _galleryStateFlow: MutableStateFlow<List<ImageItemResponse>> =
        MutableStateFlow(listOf())
    val galleryFlow = _galleryStateFlow.asStateFlow()

    private val _similarStateFlow: MutableStateFlow<List<FilmDisplayModel>> =
        MutableStateFlow(listOf())
    val similarFlow = _similarStateFlow.asStateFlow()

    private val _filmCollectionsStateFlow: MutableStateFlow<List<FilmCollectionCrossRef>> =
        MutableStateFlow(listOf())
    val filmCollectionsFlow = _filmCollectionsStateFlow.asStateFlow()

    private val _isLoadingDoneStateFlow: MutableStateFlow<Boolean> = MutableStateFlow(false)
    val isLoadingDoneFlow = _isLoadingDoneStateFlow.asStateFlow()

    var id: Int = 0
    var galleryImageCount = 0

    fun loadIt() {
        viewModelScope.run {
            launch {
                loadFilmCollections()
            }
            launch {
                _filmDataStateFlow.value = repository.getFilmDetails(id)
                if (_filmDataStateFlow.value?.serial == true) {
                    _seasonAndSeriesStateFlow.value = repository.getSeasonsForPreview(id)
                }
            }
            launch {
                _actorsStateFlow.value = repository.getActors(id)
            }
            launch {
                _staffStateFlow.value = repository.getStaff(id)
            }
            launch {
                galleryImageCount = repository.getGallery(id).first
            }
            launch {
                _galleryStateFlow.value = repository.getGallery(id).second
            }
            launch {
                _similarStateFlow.value = repository.getSimilar(id)
            }

        }
    }

    fun loadFilmCollections() {
        viewModelScope.launch {
            _filmCollectionsStateFlow.value = repository.getFilmCollections(id)
        }
    }

    fun toggleCollection(collectionId: Int) {
        viewModelScope.launch {
            val isFilmExist: FilmCollectionCrossRef? =
                repository.getFilmCollections(id).find { it.collectionId == collectionId }
            if (isFilmExist == null) {
                val film: Film? = _filmDataStateFlow.value
                val filmEntity: FilmEntity = FilmEntity(
                    id,
                    film?.posterUrl ?: "",
                    film?.nameRu ?: "",
                    film?.ratingKinopoisk ?: 0f,
                    film?.genres?.first()?.genre ?: "",
                    film?.serial == true
                )
                repository.addFilmToCollection(filmEntity, collectionId)
            } else {
                repository.removeFilmFromCollection(id, collectionId)
            }
            loadFilmCollections()
        }
    }
}